//SPDX-FileCopyrightText: Copyright 2022-2024 深圳市同心圆网络有限公司
//SPDX-License-Identifier: GPL-3.0-only

import React, { useEffect, useState } from 'react';
import { Card, Input, message, Space } from 'antd';
import { useCommonEditor } from '@/components/Editor';
import { FILE_OWNER_TYPE_PROJECT_DOC } from '@/api/fs';
import { request } from '@/utils/request';
import { observer } from 'mobx-react';
import Button from '@/components/Button';
import classNames from 'classnames';
import s from "./EditDoc.module.less";
import { type EditorRef } from '@/components/Editor/common';
import { report_error } from '@/api/client_cfg';
import { useDocStores } from '../store';
import { get_session } from '@/api/user';
import type { TocInfo } from '@/components/Editor/extensions/TocExtension';
import DocTocPanel from './DocTocPanel';
import { update_title } from "@/api/project_entry";
import { end_update_doc, keep_update_doc, start_update_doc, update_doc_content } from '@/api/project_doc';

interface WriteDocInnerProps {
  editor: React.JSX.Element;
  editorRef: React.MutableRefObject<EditorRef | null>;
  tocList: TocInfo[];
}

const WriteDocInner = observer((props: WriteDocInnerProps) => {
  const store = useDocStores();

  const [title, setTitle] = useState(store.entry?.entry_title ?? "");

  //更新文档
  const updateDoc = async () => {
    const content = props.editorRef.current?.getContent() ?? {
      type: 'doc',
    };
    const sessionId = await get_session();
    await request(
      update_doc_content({
        session_id: sessionId,
        project_id: store.projectId,
        doc_id: store.docId,
        content: JSON.stringify(content),
      }),
    );
    await request(update_title({
      session_id: sessionId,
      project_id: store.projectId,
      entry_id: store.docId,
      title: title,
    }));
    await store.loadDoc();
    store.inEdit = false;
  };

  const keepUpdateDoc = async () => {
    const sessionId = await get_session();
    await request(
      keep_update_doc({
        session_id: sessionId,
        doc_id: store.docId,
      }),
    )
  };

  const startUpdateDoc = async () => {
    const sessionId = await get_session();
    await request(
      start_update_doc({
        session_id: sessionId,
        project_id: store.projectId,
        doc_id: store.docId,
      }),
    )
  };


  const endUpdateDoc = async () => {
    const sessionId = await get_session();

    await request(end_update_doc({
      session_id: sessionId,
      doc_id: store.docId,
    }));
  };

  useEffect(() => {
    const timer = setInterval(() => {
      keepUpdateDoc().catch((e) => {
        console.log(e);
        report_error({
          err_data: `${e}`,
        });
        message.error('无法维持编辑状态');
      });
    }, 10 * 1000);
    startUpdateDoc().catch((e) => {
      console.log(e);
      report_error({
        err_data: `${e}`,
      });
      message.error('无法获得编辑权限');
    });

    return () => {
      clearInterval(timer);
      endUpdateDoc();
    };
  }, []);

  useEffect(() => {
    return () => {
      store.inEdit = false;
    };
  }, []);

  return (
    <Card bordered={false}
      title={
        <Input value={title} onChange={e => {
          e.stopPropagation();
          e.preventDefault();
          setTitle(e.target.value.trim());
        }} />
      }
      bodyStyle={{ width: "calc(100vw - 10px)" }}
      extra={
        <Space size="large" style={{ marginLeft: "100px" }}>
          <Button
            type="default"
            onClick={e => {
              e.stopPropagation();
              e.preventDefault();
              store.inEdit = false;
            }}>取消</Button>
          <Button
            type="primary"
            onClick={(e) => {
              e.stopPropagation();
              e.preventDefault();
              updateDoc();
            }}
            disabled={title == ""}
          >
            保存
          </Button>
        </Space>}>
      <div className={s.doc_wrap}>
        {props.tocList.length > 0 && <DocTocPanel tocList={props.tocList} />}
        <div className={classNames(s.read_doc, "_docContext")}>{props.editor}</div>
      </div>
    </Card>
  );
});

const WriteDoc = () => {
  const store = useDocStores();

  const [tocList, setTocList] = useState<TocInfo[]>([]);

  const { editor, editorRef } = useCommonEditor({
    content: store.doc?.base_info.content ?? "",
    fsId: store.project?.doc_fs_id ?? '',
    ownerType: FILE_OWNER_TYPE_PROJECT_DOC,
    ownerId: store.docId,
    historyInToolbar: true,
    clipboardInToolbar: true,
    commonInToolbar: true,
    pubResInToolbar: true,
    tocCallback: (result) => setTocList(result),
  });

  return (
    <WriteDocInner editor={editor} editorRef={editorRef} tocList={tocList} />
  );
};

export default observer(WriteDoc);
